﻿#include "stdafx.h"
#include <algorithm>

namespace DuiLib {
CTabLayoutUI::CTabLayoutUI() : m_iCurSel(-1)
{
}

LPCTSTR CTabLayoutUI::GetClass() const
{
    return DUI_CTR_TABLAYOUT;
}

LPVOID CTabLayoutUI::GetInterface(LPCTSTR pstrName)
{
    if (_tcscmp(pstrName, DUI_CTR_TABLAYOUT) == 0) { return static_cast<CTabLayoutUI *>(this); }

    return CContainerUI::GetInterface(pstrName);
}

bool CTabLayoutUI::Add(CControlUI *pControl)
{
    bool ret = CContainerUI::Add(pControl);

    if (!ret) { return ret; }

    if (m_iCurSel == -1 && pControl->IsVisible())
    {
        m_iCurSel = GetItemIndex(pControl);
    }
    else
    {
        pControl->SetVisible(false);
    }

    return ret;
}

bool CTabLayoutUI::AddAt(CControlUI *pControl, int iIndex)
{
    bool ret = CContainerUI::AddAt(pControl, iIndex);

    if (!ret) { return ret; }

    if (m_iCurSel == -1 && pControl->IsVisible())
    {
        m_iCurSel = GetItemIndex(pControl);
    }
    else if (m_iCurSel != -1 && iIndex <= m_iCurSel)
    {
        m_iCurSel += 1;
    }
    else
    {
        pControl->SetVisible(false);
    }

    return ret;
}

bool CTabLayoutUI::Remove(CControlUI *pControl, bool bDoNotDestroy)
{
    if (pControl == NULL) { return false; }

    int index = GetItemIndex(pControl);
    bool ret = CContainerUI::Remove(pControl, bDoNotDestroy);

    if (!ret) { return false; }

    if (m_iCurSel == index)
    {
        if (GetCount() > 0)
        {
            m_iCurSel = 0;
            GetItemAt(m_iCurSel)->SetVisible(true);
        }
        else
        { m_iCurSel = -1; }

        NeedParentUpdate();
    }
    else if (m_iCurSel > index)
    {
        m_iCurSel -= 1;
    }

    return ret;
}

void CTabLayoutUI::RemoveAll()
{
    m_iCurSel = -1;
    CContainerUI::RemoveAll();
    NeedParentUpdate();
}

int CTabLayoutUI::GetCurSel() const
{
    return m_iCurSel;
}

bool CTabLayoutUI::SelectItem(int iIndex,  bool bTriggerEvent)
{
    if (iIndex < 0 || iIndex >= m_items.GetSize()) { return false; }

    if (iIndex == m_iCurSel) { return true; }

    int iOldSel = m_iCurSel;
    m_iCurSel = iIndex;

    for (int it = 0; it < m_items.GetSize(); it++)
    {
        if (it == iIndex)
        {
            GetItemAt(it)->SetVisible(true);
            GetItemAt(it)->SetFocus();
        }
        else { GetItemAt(it)->SetVisible(false); }
    }

    NeedParentUpdate();

    if (m_pManager != NULL)
    {
        m_pManager->SetNextTabControl();

        if (bTriggerEvent) { m_pManager->SendNotify(this, DUI_MSGTYPE_TABSELECT, m_iCurSel, iOldSel); }
    }

    return true;
}

bool CTabLayoutUI::SelectItem(CControlUI *pControl, bool bTriggerEvent)
{
    int iIndex = GetItemIndex(pControl);

    if (iIndex == -1) { return false; }
    else              { return SelectItem(iIndex, bTriggerEvent); }
}

void CTabLayoutUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{
    if (_tcscmp(pstrName, _T("selectedid")) == 0) { SelectItem(ParseInt(pstrValue), false); }
    else if (_tcscmp(pstrName, _T("autowidth")) == 0) { DUITRACE(_T("不支持属性:autowidth")); }
    else if (_tcscmp(pstrName, _T("autoheight")) == 0) { DUITRACE(_T("不支持属性:autoheight")); }
    else { CContainerUI::SetAttribute(pstrName, pstrValue); }
}

void CTabLayoutUI::SetPos(RECT rc, bool bNeedInvalidate)
{
    CControlUI::SetPos(rc, bNeedInvalidate);
    rc = m_rcItem;

    // Adjust for inset
    // 2019-05-30 zhuyadong 排除边框占用的空间
    rc.left += (m_rcBorderSize.left + m_rcPadding.left);
    rc.top += (m_rcBorderSize.top + m_rcPadding.top);
    rc.right -= (m_rcBorderSize.right + m_rcPadding.right);
    rc.bottom -= (m_rcBorderSize.bottom + m_rcPadding.bottom);

    for (int it = 0; it < m_items.GetSize(); it++)
    {
        CControlUI *pControl = static_cast<CControlUI *>(m_items[it]);

        if (!pControl->IsVisible()) { continue; }

        if (pControl->IsFloat())
        {
            SetFloatPos(it);
            continue;
        }

        if (it != m_iCurSel) { continue; }

        RECT rcMargin = pControl->GetMargin();
        rc.left += rcMargin.left;
        rc.top += rcMargin.top;
        rc.right -= rcMargin.right;
        rc.bottom -= rcMargin.bottom;

        SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top };

        SIZE sz = pControl->EstimateSize(szAvailable);

        if (sz.cx == 0)
        {
            sz.cx = std::max<int>(0, szAvailable.cx);
        }

        if (sz.cx < pControl->GetMinWidth()) { sz.cx = pControl->GetMinWidth(); }

        if (sz.cx > pControl->GetMaxWidth()) { sz.cx = pControl->GetMaxWidth(); }

        if (sz.cy == 0)
        {
            sz.cy = std::max<int>(0, szAvailable.cy);
        }

        if (sz.cy < pControl->GetMinHeight()) { sz.cy = pControl->GetMinHeight(); }

        if (sz.cy > pControl->GetMaxHeight()) { sz.cy = pControl->GetMaxHeight(); }

        RECT rcCtrl = { rc.left, rc.top, rc.left + sz.cx, rc.top + sz.cy};
        pControl->SetPos(rcCtrl, false);
    }
}
}
